package com.road.yishi.admincmd;

import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.road.common.utils.PackageUtils;
import com.road.yishi.base.AdminCmd;

/**
 * @Description :后台管理URI映射
 * @FileName: RequestMapping.java
 * @Author :WeiHui.Zhang
 * @Data : 2016年2月17日 下午5:57:35
 * @Version:V1.00
 */
public final class RequestMapping {

	private static final Logger LOGGER = LoggerFactory.getLogger(RequestMapping.class);

	private static final Map<String, AdminCommand> adminCmdCache = Maps.newConcurrentMap();

	private static void initMapping(String packageName) {
		LOGGER.info("handles begin initiating");
		Set<String> cmdSet = Sets.newHashSet();
		LOGGER.info("begin get classes from package {} : ", packageName);
		Set<String> classNames = PackageUtils.findClassesInPackage(packageName);
		for (String className : classNames) {
			try {
				Class<?> cmdClass = Class.forName(className);
				AdminCmd cmd = cmdClass.getAnnotation(AdminCmd.class);
				if (cmd == null) {
					continue;
				}
				String uri = cmd.value();
				String desc = cmd.desc();
				if (checkCommand(cmdSet, className, uri)) {
					AdminCommand newInstance = (AdminCommand) cmdClass.newInstance();
					adminCmdCache.put(uri, newInstance);
					LOGGER.info("[REQUEST MAPPING] ==> path : {} , name : {} , desc : {}", uri, className, desc);
				}
			} catch (Exception e) {
				LOGGER.error("load command fail, command name : " + className, e);
			}
		}
	}

	public static AdminCommand getAdmincmdByPath(String path) {
		if (adminCmdCache.size() > 0) {
			return adminCmdCache.get(path);
		} else {
			LOGGER.error("adminCmdCache size() = 0, Please apply RequestMapping.init() first!");
			return null;
		}
	}

	private static boolean checkCommand(Set<String> cmdSet, String className, String uri) {
		if (cmdSet.contains(uri)) {
			LOGGER.error("协议冲突，类：{} ,访问路径： {} !", className, uri);
			return false;
		} else {
			cmdSet.add(uri);
			return true;
		}
	}

	public static void init(String packageName) {
		initMapping(packageName);
	}
}
